﻿using System;
using System.Diagnostics;
using System.Text;

namespace BoldBrick.Core.Logging
{
	/// <summary>
	/// This class provides logging into trace
	/// </summary>
    public class TraceLogger : ILogger
    {

		#region ------ Implementation of ILogger --------------------------------------------------

		public bool IsEnabled(LogLevel level)
		{
			return true;
		}

		
		public void Write(LogLevel level, Exception ex, string message, params object[] pars)
		{
			if (message == null)
				throw new ArgumentNullException("message");
		}

		
		public void Write(LogLevel level, string message, params object[] pars)
		{
			if (message == null)
				throw new ArgumentNullException("message");

			InnerWrite(level, string.Format(message, pars));
		}

		
		public void LogIfEnabled(LogLevel level, Func<LogDetails> details)
		{
			if (details == null)
				throw new ArgumentNullException("details");

			var par = details();
			if (par.Exception == null)
				InnerWrite(level, par.Message);
			else
				InnerWriteException(level, par.Exception, par.Message);
		}

		#endregion

        /// <summary>
        /// Write a record into trace
        /// </summary>
        /// <param name="level">Level of the record</param>
        /// <param name="ex">Exception of the record</param>
        /// <param name="content">Message of the record</param>
		private static void InnerWriteException(LogLevel level, Exception ex, string content)
        {
            if (ex == null)
                throw new ArgumentNullException("ex");
            if (content == null)
                throw new ArgumentNullException("content");

            var sb = new StringBuilder();
            sb.AppendLine(content);
            sb.AppendLine(ex.Message);
            sb.AppendLine(ex.StackTrace);

            InnerWrite(level, sb.ToString());
        }

		/// <summary>
		/// Write a record into trace
		/// </summary>
		/// <param name="level">Level of the record</param>
		/// <param name="content">Message of the record</param>
		private static void InnerWrite(LogLevel level, string content)
        {
            if (content == null)
                throw new ArgumentNullException("content");

            switch (level)
            {
                case LogLevel.Debug:
                case LogLevel.Info:
                    Trace.TraceInformation(content);
                    break;
                case LogLevel.Error:
                case LogLevel.Fatal:
                    Trace.TraceError(content);
                    break;
                case LogLevel.Warn:
                    Trace.TraceWarning(content);
                    break;
            }
        }
    }
}
